0%

Java 与Cpp若干比较

默认权限的比较

Java Cpp 备注
权限关键字 public、protect、default、private public、protect、friend、private Cpp中friend实际打破了类的封装
默认权限 default(friendly) 仅内部和同包(有继承)可以使用 private,仅内部可以使用,继承类和子类均无法使用 参考链接_带实例参考链接2
对外可见性 Java通过包名定义可见范围,没有全局变量 通过命名空间定义,有全局变量

多态实现

  1. Java中是除了static ,final,private等可以在编译器确定的类别外,其余都是在后期绑定 ,Cpp中是前期绑定。 Java中继承类是父类的一种新类型
  2. Cpp通过virtual 虚函数完成动态绑定
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
class Shape {
void draw() {
}
}

class Circle extends Shape {
void draw() {
System.out.println("Circle.draw()");
}

}

class Square extends Shape {
void draw() {
System.out.println("Square.draw()");
}

}

public class test {

public static Shape randShape(int choice) {

switch (choice) {
default: // To quiet the compiler
case 0:
return new Circle();
case 1:
return new Square();

}
}

public static void main(String[] args) {
Shape[] s = new Shape[2];
// Fill up the array with shapes:
for (int i = 0; i < s.length; i++)
s[i] = randShape(i);
// Make polymorphic method calls:
for (int i = 0; i < s.length; i++)
s[i].draw();
}
}

输出结果

1
2
Circle.draw()
Square.draw()

可以看出,Java中通过后期绑定的方法,在继承类中改写父类信息,可以直接通过父类访问子类变量和函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class Shape {
public:
void draw() {
cout << "Shape draw()" << endl;
}

};

class Circle:public Shape {
public:
void draw() {
cout << "Circle.draw()" << endl;
}



};

class Square :public Shape {
public:
void draw() {
cout << "Square.draw()" << endl;
}

};
int main() {

Shape *s1 =new Circle(),*s2= new Square();
s1->draw();
s2->draw();
system("pause");
return 0;
}

输出结果

1
2
Shape draw()
Shape draw()

如果需要完成动态绑定,得到Java程序的输出,需要添加vitrual,将Shape改成如下形式;

1
2
3
4
5
6
7
class Shape {
public:
virtual void draw() {
cout << "Shape draw()" << endl;
}

};

需要注意的是,基于指针的虚函数表,只有存在指针的时候虚函数才会改变指向,如上采用如下方式

1
2
3
4
5
6
7
8
int main() {

Shape s1 =Circle(),s2= Square();
s1.draw();
s2.draw();
system("pause");
return 0;
}

永远都是输出Shape的信息,因为s1,s2定义在栈空间,只会存在栈顶指针的移动。

重载与重写

  1. 重写需要保证函数名,返回值,参数列表一致(Cpp与Java相同)
  2. Java中的重载可以跨越子类与继承类
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    class A_base{
    public final static int static_value =1;
    }
    class Shape {
    void draw() {
    }
    void draw(int x) {
    System.out.println("Shape draw");
    }

    }

    class Circle extends Shape {
    void draw() {
    System.out.println("Circle.draw()");
    }
    //实际是重载
    void draw(A_base x) {
    System.out.println("Circle draw");
    }
    }

    public class test {

    public static void letsdarw(Shape s) {
    s.draw(A_base.static_value);//实际调用的是s.draw(int value)

    }

    public static void main(String[] args) {
    Circle circle = new Circle();
    A_base a_base = new A_base();
    circle.draw(a_base);
    letsdarw(circle);
    }
    }

输出结果

1
2
Circle draw
Shape draw

坚持原创技术分享,您的支持将鼓励我继续创作!